package game.games.world;

import game.IImageRenderer;
import game.Position;
import game.cellmap.CellMap;
import game.coord.VonNeumannCell;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Region extends VonNeumannCell<Region> implements IImageRenderer
{
    public final static int DEFAULT_SIZE = 4;
    
    private int             size;
    private static int      zoneSize     = 5;
    private List<ZoneType>  zones;
    private CellMap         map;
    private boolean         resetImage   = true;
    private BufferedImage   image;
    
    private Region(int size, ZoneType... zones)
    {
        if (zones == null)
        {
            if (size == 0)
            {
                throw new IllegalArgumentException("empty region");
            }
            List<ZoneType> zoneList = new ArrayList<ZoneType>();
            while (zoneList.size() < (size * size))
            {
                zoneList.add(ZoneType.OCEAN);
            }
            zones = zoneList.toArray(new ZoneType[zoneList.size()]);
        }
        else
        {
            if (size > 0 && zones.length > 0)
            {
                throw new IllegalArgumentException("can not init with size and zones");
            }
        }
        if (zones.length == 0)
        {
            throw new IllegalArgumentException("zones is empty");
        }
        if (zones.length % 2 != 0)
        {
            throw new IllegalArgumentException(zones.length + " is not square!");
        }
        this.size = size;
        this.zones = new ArrayList<ZoneType>();
        this.zones.addAll(Arrays.asList(zones));
        reset();
    }
    
    public Region()
    {
        this(DEFAULT_SIZE, (ZoneType[]) null);
    }
    
    public int getSize()
    {
        return size;
    }
    
    public static int getMapSize()
    {
        return DEFAULT_SIZE * zoneSize;
    }
    
    public void reset()
    {
        this.map = new CellMap(false, zoneSize);
        this.map.setMapSize(new Position(this.size, this.size));
    }
    
    public void setZoneSize(int zoneSize)
    {
        Region.zoneSize = zoneSize;
    }
    
    public int getZoneSize()
    {
        return zoneSize;
    }
    
    public void overrideZoneTypes(ZoneType zoneType)
    {
        for (int index = 0; index < zones.size(); index++)
        {
            zones.set(index, zoneType);
        }
        resetImage = true;
    }
    
    @Override
    public BufferedImage getImage()
    {
        if (resetImage)
        {
            BufferedImage image = new BufferedImage(getMapSize(), getMapSize(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = image.createGraphics();
            for (int index = 0; index < zones.size(); index++)
            {
                ZoneType zone = zones.get(index);
                Position position = map.calculatePosition(index);
                Color color = zone.getColor();
                map.fillRect(g, position, color);
            }
            this.image = image;
            resetImage = false;
        }
        return this.image;
    }
}
